#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include "binary.h"


int
test_short()
{
	u_int8_t *buffer = malloc(0);
	if (buffer == NULL)
		return -1;
	Writer writer = { .buffer = buffer, .offset = 0, .size = 0 };
	if (writeshort(&writer, Big, 256) != 0)
		return -1;
	assert(buffer[0] == 1 && buffer[1] == 0);
	Reader reader = { .buffer = buffer, .offset = 0, .size = 2 };
	u_int16_t result = 0;
	if (readshort(&reader, &result, Big) != 0)
		return -1;
	assert(result == 256);
	writer.offset = 0;
	if (writeshort(&writer, Little, 256) != 0)
		return -1;
	reader.offset = 0;
	assert(buffer[0] == 0 && buffer[1] == 1);
	if (readshort(&reader, &result, Little) != 0)
		return -1;
	assert(result == 256);
	free(buffer);
}

int
test_triad()
{
	u_int8_t *buffer = malloc(0);
	if (buffer == NULL)
		return -1;
	Writer writer = { .buffer = buffer, .offset = 0, .size = 0 };
	if (writetriad(&writer, Big, 65536) != 0)
		return -1;
	assert(buffer[0] == 1 && buffer[1] == 0 && buffer[2] == 0);
	Reader reader = { .buffer = buffer, .offset = 0, .size = 3 };
	u_int32_t result = 0;
	if (readtriad(&reader, &result, Big) != 0)
		return -1;
	assert(result == 65536);
	writer.offset = 0;
	if (writetriad(&writer, Little, 65536) != 0)
		return -1;
	reader.offset = 0;
	assert(buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 1);
	if (readtriad(&reader, &result, Little) != 0)
		return -1;
	assert(result == 65536);
	free(buffer);
}

int
test_int()
{
	u_int8_t *buffer = malloc(0);
	if (buffer == NULL)
		return -1;
	Writer writer = { .buffer = buffer, .offset = 0, .size = 0 };
	if (writeint(&writer, Big, 16777216) != 0)
		return -1;
	assert(buffer[0] == 1 && buffer[1] == 0 && buffer[2] == 0 && buffer[3] == 0);
	Reader reader = { .buffer = buffer, .offset = 0, .size = 4 };
	u_int32_t result = 0;
	if (readint(&reader, &result, Big) != 0)
		return -1;
	assert(result == 16777216);
	writer.offset = 0;
	if (writeint(&writer, Little, 16777216) != 0)
		return -1;
	reader.offset = 0;
	assert(buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0 && buffer[3] == 1);
	if (readint(&reader, &result, Little) != 0)
		return -1;
	assert(result == 16777216);
	free(buffer);
}

int
test_long()
{
	u_int8_t *buffer = malloc(0);
	if (buffer == NULL)
		return -1;
	Writer writer = { .buffer = buffer, .offset = 0, .size = 0 };
	if (writelong(&writer, Big, 72057594037927936) != 0)
		return -1;
	assert(buffer[0] == 1 && buffer[1] == 0 && buffer[2] == 0 && buffer[3] == 0 && buffer[4] == 0 && buffer[5] == 0 && buffer[6] == 0 && buffer[7] == 0);
	Reader reader = { .buffer = buffer, .offset = 0, .size = 8 };
	u_int64_t result = 0;
	if (readlong(&reader, &result, Big) != 0)
		return -1;
	assert(result == 72057594037927936);
	writer.offset = 0;
	if (writelong(&writer, Little, 72057594037927936) != 0)
		return -1;
	reader.offset = 0;
	assert(buffer[0] == 0 && buffer[1] == 0 && buffer[2] == 0 && buffer[3] == 0 && buffer[4] == 0 && buffer[5] == 0 && buffer[6] == 0 && buffer[7] == 1);
	if (readlong(&reader, &result, Little) != 0)
		return -1;
	assert(result == 72057594037927936);
	free(buffer);
}

void
message(const char *msg)
{
	printf("test `%s` failed!\n", msg);
}

int
main(void)
{
	if (test_short() != 0)
		message("test_short");
	if (test_triad() != 0)
		message("test_triad");
	if (test_int() != 0)
		message("test_int");
	if (test_long() != 0)
		message("test_int");
	return 0;
}
